package com.powergame.main;

import com.powergame.model.Equipe;
import com.powergame.model.Plateau;
import com.powergame.model.Secteur;
import com.powergame.model.TypeSecteur;
import java.awt.Polygon;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.xpath.XPath;

/**
 * XMLPlateauLoader.java
 *
 * Se charge de créer un plateau de jeu à partir d'un fichier XML
 *
 * @author ToF
 */
public class XMLPlateauLoader {

    private static Logger log = Logger.getLogger(XMLPlateauLoader.class.getName());
    
    /**
     * Lecture du fichier XML, création et initialisation du plateau de jeu
     * 
     * @param nomFichierXML le fichier source 
     * 
     * @return  le plateau crée
     */
    public static Plateau loadPlateau(String nomFichierXML){
        
        log.entering("XMLPlateauLoader", "loadPlateau");
        
        Plateau plateau = null;
        
        try {
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(new File(nomFichierXML));
            
            plateau = new Plateau(null);
            
            Map<String, Secteur> secteurs = new HashMap<String, Secteur>();
            
            // Lecture des propriétés des secteurs
            XPath xp = XPath.newInstance("/map/secteurs/secteur");
            List<Element> eSecteurs = (List<Element>) xp.selectNodes(doc);
            Secteur s = null;
            for(Element e : eSecteurs){
                
                s = new Secteur(plateau, e.getAttributeValue("id"), 
                                         TypeSecteur.parseTypeSecteur(e.getAttributeValue("type")), 
                                         Equipe.parseEquipe(e.getAttributeValue("equipe")));
                secteurs.put(s.getId(), s);
                
                
                if(e.getChild("polygone") != null){
                    // Lecture des coordonnées
                    Polygon poly = new Polygon();
                    for(Element p : e.getChild("polygone").getChildren()){
                        poly.addPoint(Integer.parseInt(p.getAttributeValue("x")), Integer.parseInt(p.getAttributeValue("y")));
                    }
                    s.setPolygone(poly);
                }
                System.out.println("Secteur: " + s.getId() + " : " + s);
                plateau.ajouteSecteur(s);
            }
            
            // Tissage du réseau de secteur
            xp = XPath.newInstance("/map/plateau/secteur");
            eSecteurs = (List<Element>)xp.selectNodes(doc);
            List<Element> eVoisins = null;
            Secteur voisin = null;
            
            for(Element e : eSecteurs){
                
                s = secteurs.get(e.getAttributeValue("id"));
                if(s != null){
                    eVoisins = e.getChildren();
                    for(Element v : eVoisins){
                        voisin = secteurs.get(v.getAttributeValue("id"));
                        if(voisin == null){
                            throw new NullPointerException("Le voisin '" + v.getAttributeValue("id") + " ' de " + s.getId() + " n'existe pas !");
                            
                        }else{
                            s.ajouteVoisin(voisin);
                        }
                    }
                    
                }else{
                    throw new NullPointerException("Le secteur '" + e.getAttributeValue("id") + " ' n'existe pas !");
                }
            }
            
        } catch (JDOMException ex) {
            Logger.getLogger(XMLPlateauLoader.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(XMLPlateauLoader.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        log.entering("XMLPlateauLoader", "loadPlateau");
        
        return plateau;
    }
}
